/*
 * frustum.h
 *
 *  Created on: 18-jun-2009
 *      Author: HPK
 */

#ifndef FRUSTUM_H_
#define FRUSTUM_H_


/*

Generalizando
z => seria la direccion (at-eye)
y => seria el up vector
fovy => fov en up
x => normal a (at-eye) y up

y(entrante)
 X_____ x
 |
 |
 |z

           ^eye                             -		-
          /|\								|		|
         / | \								|		|
        /  |  \								|		|
       /  fovy \ -> angulo de apertura en y	| dNear	|
      /    |    \							|		|
(p4) /     |     \(p3)						|		|
 p1 /______.______\p2 ->frontface			-		|
   /       |       \								|
  /        |        \								| dFar
 /         |         \								|
/__________.__________\								-
p5                	   p6 ->backFace
(p8)					(p7)

()-> abajo

*/

#include "cube.h"
#include "matrix4x4.h"

class Frustum{
	private:
		// 4 primeros -> fronFace
		// 4 ultimos  -> backFace
		Point _vertices[8];
		Point _normals[6];
		Point _eye;
		Point _at;
		Point _up;

		void calculateNormals(Point* normals);
	public:
		// El angulo fovUp debe pasarse en radianes
		// dFar > dNear > 0
		// (at-eye)*up = 0
		// 1>=aspect>0
		// TODO No se comprueba que se cumplan las restrucciones anteriores
		Frustum(Point eye,Point at,Point up,float fovUp,float aspect,float dNear,float dFar);
		~Frustum();

		void updateFrustum(Point eye,Point at,Point up,float fovUp,float aspect,float dNear,float dFar);
		bool intersect(const Cube& cube)const;

		Point getEye();
		Point getAt();
		Point getUp();
		Point getFrustumUp();
		void  setUp(const Point& up);

		void applyTransformation(const Matrix4x4& m);
		void transformUp(const Matrix4x4& m);

		const Point* frontFace()const{ return _vertices; }
		const Point* backFace()const{ return _vertices+4; }
		const Point* normals()const{ return _normals; }
};

#endif /* FRUSTUM_H_ */
